home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / HASWIN / HASWIN3 / _files / _haswin / WINDOW._c < prev    next >
Text File  |  1991-05-27  |  20KB  |  526 lines

  1. /* > $.CLIB.C.window
  2.  *
  3.  *      HASWIN Graphics Library
  4.  *     =========================
  5.  *
  6.  *      Copyright (C) H.A.Shaw 1990.
  7.  *              Howard A. Shaw.
  8.  *              The Unit for Space Sciences,
  9.  *              Room 165,
  10.  *              Physics Building,
  11.  *              University of Kent at Canterbury.
  12.  *              Canterbury.
  13.  *              Kent.  CT2 7NJ
  14.  *      You may use and distribute this code freely, however please leave
  15.  *      it alone.  If you find bugs (and there will be many) please contact
  16.  *      me and the master source can be modified.  If you keep me informed
  17.  *      of who you give copies of this to then I can get release upgrades
  18.  *      to them.
  19.  *
  20.  *      window creation routines.
  21.  */
  22. #include "includes.h"
  23.  
  24. window *haswin_makewindow(char *title, int x, int y, int tf, int tb, int wf, int wb, int flags) {
  25.  
  26.         _kernel_swi_regs        regs;
  27.         window                  *wptr;
  28.  
  29.         if (flags & WINDOW_AUTOTEXT) {
  30.                 x = 1 + x/haswin_readvduvariable(VDUVAR_CharXsize);
  31.                 x = x*haswin_readvduvariable(VDUVAR_CharXsize);
  32.                 y = 1 + y/haswin_readvduvariable(VDUVAR_CharYsize);
  33.                 y = y*haswin_readvduvariable(VDUVAR_CharYsize);
  34.         }
  35.         wptr=(window *)haswin_malloc(sizeof(window), "haswin_makewindow", "window structure");
  36.         wptr->win=haswin_malloc(88, "haswin_makewindow", "window");
  37.         ((int *)wptr->win)[ 0] = 0;           /* visible area x0           */
  38.         ((int *)wptr->win)[ 1] = -y;          /* visible area y0           */
  39.         ((int *)wptr->win)[ 2] = x;           /* visible area x1           */
  40.         ((int *)wptr->win)[ 3] = 0;           /* visible area y1           */
  41.         ((int *)wptr->win)[ 4] = 0;           /* visible area scroll x     */
  42.         ((int *)wptr->win)[ 5] = 0;           /* visible area scroll y     */
  43.         ((int *)wptr->win)[ 6] = -1;          /* open on top of stack      */
  44.         ((int *)wptr->win)[ 7] =
  45.              ((flags&WINDOW_WIMPFLAGS)|WINDOW_FLAGS_OR) & ~WINDOW_FLAGS_AND;
  46.                                               /* window flags              */
  47.         wptr->win[32] = tf;                   /* title  forground          */
  48.         wptr->win[33] = tb;                   /* title background          */
  49.         wptr->win[34] = wf;                   /*  work  forground          */
  50.         wptr->win[35] = wb;                   /*  work background          */
  51.         wptr->win[36] = tb;                   /* scroll bars fore          */
  52.         wptr->win[37] = tf;                   /* scroll bars back          */
  53.         wptr->win[38] = 0;                    /* selection colour          */
  54.         wptr->win[39] = 0;
  55.  
  56.         ((int *)wptr->win)[10] = 0;           /* work area x0              */
  57.         ((int *)wptr->win)[11] = -y;          /* work area y0              */
  58.         ((int *)wptr->win)[12] = x;           /* work area x1              */
  59.         ((int *)wptr->win)[13] = 0;           /* work area y1              */
  60.         ((int *)wptr->win)[14] = 0x0000013D;  /* title bar icon flags      */
  61.         ((int *)wptr->win)[15] = flags & 0x0000F000;
  62.                                               /* work area button type     */
  63.         wptr->button = (flags>>12) & 0x0F;
  64. /* choose a sprite area control block. */
  65. /* if a specific area is not chosen, then choose the WIMP +1 area */
  66.         switch (flags & SPRITE_AREA_MASK) {
  67.         case SPRITE_SYSTEM_AREA:
  68.                 ((int *)wptr->win)[16] = 0;
  69.                 break;
  70.         case SPRITE_WIMP_AREA:
  71.         case SPRITE_RISCOS_AREA:
  72.                 ((int *)wptr->win)[16] = 1;
  73.                 break;
  74.         case SPRITE_HASWIN_AREA:
  75.                 ((int *)wptr->win)[16] = (int)haswin_haswinsprites;
  76.                 break;
  77.         case SPRITE_USER_AREA:
  78.                 ((int *)wptr->win)[16] = (int)haswin_usersprites;
  79.                 break;
  80.         default:
  81.                 haswin_interrorprintf("haswin_makewindow: unknown sprite area %8.8X", flags & SPRITE_AREA_MASK);
  82.                 /* FALL THRU */
  83.         case 0:
  84.                 ((int *)wptr->win)[16] = +1;
  85.                 break;
  86.         }
  87.         ((int *)wptr->win)[17] = 0;           /* window min width/height   */
  88.         ((int *)wptr->win)[18] = (int)haswin_malloc(asciilen(title)+1, "haswin_makewindow:", "window title");
  89.         strcpy((char *)((int *)wptr->win)[18], title);
  90.         ((int *)wptr->win)[19] = -1;
  91.         ((int *)wptr->win)[20] = asciilen(title);
  92.         ((int *)wptr->win)[21] = 0;           /* number of icons initially */
  93.         regs.r[1] = (int)wptr->win;
  94.         if (!haswin_swi(HASWIN_Create_window, ®s))
  95.                 return(HASWIN_FALSE);
  96.         wptr->handle = regs.r[0];
  97.         haswin_newwindowflags(wptr, flags);
  98.         wptr->orgx = wptr->orgy = 0;
  99.         wptr->mousebutton = (int (*)())0;
  100.         wptr->drawroutine = (int (*)())0;
  101.         wptr->openroutine = (int (*)())0;
  102.         wptr->keyroutine = (int (*)())0;
  103.         wptr->dragroutine = (int (*)())0;
  104.         wptr->name = haswin_malloc(asciilen(title)+1, "haswin_makewindow:", "window name");
  105.         strcpy(wptr->name, title);
  106.         wptr->pointer = (pointer *)0;
  107.         wptr->text = (text *)0;
  108.         wptr->caret = (caret *)0;
  109.         wptr->menu = (menu *)0;
  110.         wptr->scrollx = wptr->scrolly = wptr->pagex = wptr->pagey = 0;
  111.         wptr->numicons = 0;
  112.         wptr->icons = (icon *)0;
  113.         wptr->picture = (char *)0;
  114.         wptr->help = (window *)0;
  115.         wptr->helpmsg = (char *)0;
  116.         wptr->master = wptr;                  /* window is its own master */
  117.         wptr->next = haswin_topwindow;
  118.         haswin_topwindow = wptr;
  119.         wptr->pane = wptr->slide = (window *)0;
  120.         if (flags & WINDOW_AUTOTEXT) {
  121.                 haswin_maketextoverlay(wptr, x/haswin_readvduvariable(VDUVAR_CharXsize),y/haswin_readvduvariable(VDUVAR_CharYsize), wf, wb);
  122.         }
  123.         return(wptr);
  124. }
  125.  
  126. window *haswin_makepanewindow(window *top, char *title, int x, int y, int tf, int tb, int wf, int wb, int flags) {
  127.  
  128.         window  *win;
  129.  
  130.         if ((win=haswin_makewindow(title, x, y, tf, tb, wf, wb, flags)) == 0)
  131.                 return(HASWIN_FALSE);
  132.         win->master = top;
  133.         while (top->pane)
  134.                 top=top->pane;
  135.         top->pane = win;
  136.         return(win);
  137. }
  138.  
  139. window *haswin_makeslidewindow(window *top, char *title, int x, int y, int tf, int tb, int wf, int wb, int flags) {
  140.  
  141.         window  *win;
  142.  
  143.         if ((win=haswin_makewindow(title, x, y, tf, tb, wf, wb, flags)) == 0)
  144.                 return(HASWIN_FALSE);
  145.         win->master = top;
  146.         while (top->slide)
  147.                 top=top->slide;
  148.         top->slide = win;
  149.         return(win);
  150. }
  151.  
  152. /*
  153.  *      copy the window pointed to by win.
  154.  *      Copy window contents, pointers data areas etc.
  155.  *      Create all the icons required.
  156.  */
  157. window *haswin_copywindow(window *org) {
  158.  
  159.         _kernel_swi_regs  regs;
  160.         icon    *ic;
  161.         window  *wptr;
  162.         int     i, master=HASWIN_FALSE;
  163.         char    *cptr;
  164. /*
  165.  * copywindow is recursive, but must keep a global variable for the master
  166.  * window in a pane or slide group.  The bit of magic associated with the
  167.  * next two 'static' variables achieves this (I hope).
  168.  */
  169. static int      level = 0;
  170. static window   *masterwin;
  171.  
  172.         if ((int)org <= 0)
  173.                 return((window *)0);
  174.         wptr=(window *)haswin_malloc(sizeof(window), "haswin_copywindow", "wptr");
  175.         if (level++ == 0) {
  176.                 master = HASWIN_TRUE;
  177.                 masterwin = wptr;
  178.         }
  179.         memcpy(wptr, org, sizeof(window));
  180.         /*
  181.          *      we have copied all data, including pointers, so recreate
  182.          *      pointers in wptr using haswin_malloc as needed.
  183.          */
  184.         wptr->master = masterwin;
  185.         if (org->pointer) {
  186.                 /* copy mouse pointer shape to use */
  187.                 wptr->pointer = (pointer *)haswin_malloc(sizeof(pointer), "haswin_copywindow", "pointer");
  188.                 memcpy(wptr->pointer, org->pointer, sizeof(pointer));
  189.                 if (org->pointer->palette)
  190.                         wptr->pointer->palette = haswin_malloc(sizeof(palette), "haswin_copywindow", "pointer palette");
  191.  
  192.                         memcpy(wptr->pointer->palette, org->pointer->palette, sizeof(palette));
  193.         }
  194.         if (org->text) {
  195.                 /* copy text area */
  196.                 haswin_maketextoverlay(wptr, org->text->xsize, org->text->ysize, org->text->fcol, org->text->bcol);
  197.                 memcpy(wptr->text->text, org->text->text, org->text->xsize*org->text->ysize);
  198.                 wptr->text->xposn = org->text->xposn;
  199.                 wptr->text->yposn = org->text->yposn;
  200.                 wptr->text->fcol = org->text->fcol;
  201.                 wptr->text->bcol = org->text->bcol;
  202.         }
  203.         if (org->caret) {
  204.                 /* copy caret to use */
  205.                 wptr->caret = (caret *)haswin_malloc(sizeof(caret), "haswin_copywindow", "caret");
  206.                 memcpy(wptr->caret, org->caret, sizeof(caret));
  207.         }
  208.         if (org->menu) {
  209.                 /* copy menu */
  210.                 wptr->menu = (menu *)haswin_malloc(sizeof(menu), "haswin_copywindow", "menu");
  211.                 memcpy(wptr->menu, org->menu, sizeof(menu));
  212.                 if (org->menu->menu) {
  213.                         wptr->menu->menu = (char *)haswin_malloc(asciilen(org->menu->menu)+1, "haswin_copywindow", "menu data");
  214.                         strcpy(wptr->menu->menu, org->menu->menu);
  215.                 }
  216.                 wptr->menu->actual   = 0;
  217.                 wptr->menu->ifrom    = -1;
  218.                 wptr->menu->wfrom    = org->handle;
  219.         }
  220.         if (org->name) {
  221.                 /*
  222.                  *      copy window name
  223.                  */
  224.                 wptr->name = (char *)haswin_malloc(asciilen(org->name)+1, "haswin_copywindow", "window name");
  225.                 strcpy(wptr->name, org->name);
  226.         }
  227.         /*
  228.          *      create window WINDOW structure
  229.          */
  230.         wptr->win = (char *)haswin_malloc(92+(org->numicons*32), "haswin_copywindow", "window win block");
  231.         /*
  232.          *      get window WINDOW structure contents from WIMP
  233.          */
  234.         ((int *)wptr->win)[0] = org->handle;
  235.         regs.r[1] = (int)wptr->win;
  236.         haswin_swi(HASWIN_Get_window_info, ®s);
  237.         if (((int *)wptr->win)[22] != org->numicons) {
  238.                 /*
  239.                  *     there might have been icons defined in the window
  240.                  *     since the original creation that we don't know about
  241.                  *     (user not using haswin_ routines! )If so we might have
  242.                  *     just overwritten something important with the SWI.
  243.                  */
  244.                 haswin_errorbox("The HASWIN library has had an internal inconsistancy and must exit (haswin_copywindow)");
  245.                 haswin_exit(HASWIN_FALSE);
  246.         }
  247.         /*
  248.          *      move the window structure along the buffer an integer
  249.          */
  250.         for (i=0; i<22+(org->numicons*8); i++)
  251.                 ((int *)wptr->win)[i] = ((int *)wptr->win)[i+1];
  252.         /*
  253.          *      make the window flags correct
  254.          */
  255.         ((int *)(wptr->win))[7] = ((((int *)wptr->win)[7] & WINDOW_WIMPFLAGS) | WINDOW_FLAGS_OR) & WINDOW_FLAGS_AND;
  256.         /*
  257.          *      now we actually create the new, copied window
  258.          */
  259.         regs.r[1] = (int)wptr->win;
  260.         if (!haswin_swi(HASWIN_Create_window, ®s)) {
  261.                 /* we have failed to create the window, clear up */
  262.                 haswin_free(wptr->win);
  263.                 if (wptr->name)
  264.                         haswin_free(wptr->name);
  265.                 if (wptr->menu) {
  266.                         if (wptr->menu->menu)
  267.                                 haswin_free(wptr->menu->menu);
  268.                         haswin_free(wptr->menu);
  269.                 }
  270.                 if (wptr->caret)
  271.                         haswin_free(wptr->caret);
  272.                 if (wptr->pointer) {
  273.                         if (wptr->pointer->palette)
  274.                                 haswin_free(wptr->pointer->palette);
  275.                         haswin_free(wptr->pointer);
  276.                 }
  277.                 haswin_free(wptr);
  278.                 return(0);
  279.         }
  280.         wptr->handle = regs.r[0];
  281.         /*
  282.          *      add the icon definitions to the internal icons list
  283.          */
  284.         wptr->icons = (icon *)0;
  285.         for (i=0; i<wptr->numicons; i++) {
  286.                 ic=(icon *)haswin_malloc(sizeof(struct icon), "haswin_copywindow", "icon");
  287.                 ic->whandle = wptr->handle;
  288.                 ic->ihandle = i;
  289.                 ic->ic = (int *)&(wptr->win[88+i*32]);
  290.                 ic->window = (window *)0;
  291.                 ic->menu = (menu *)0;
  292.                 ic->mousebutton = (int (*)())0;
  293.                 ic->dragroutine = (int (*)())0;
  294.                 ic->flags = 0;
  295.                 ic->help = (window *)0;
  296.                 wptr->helpmsg = (char *)0;
  297.                 ic->next = wptr->icons;
  298.                 wptr->icons = ic;
  299.                 cptr=haswin_geticontitle(ic);
  300.                 ic->name = (char *)haswin_malloc(asciilen(cptr)+1, "haswin_copywindow", "icon name");
  301.                 strcpy(ic->name, cptr);
  302.         }
  303.         if (org->picture) {
  304.                 /*
  305.                  *      the copied window must contain a graphic, so copy it
  306.                  */
  307.                 wptr->picture = (char *)haswin_mallocblock(0, ((int *)org->picture)[-1], "haswin_copywindow", "picture");
  308.                 strncpy(wptr->picture, org->picture, ((int *)org->picture)[-1]);
  309.         } else
  310.                 wptr->picture = (char *)0;
  311.         wptr->next = haswin_topwindow;
  312.         haswin_topwindow = wptr;
  313.         if (org->pane)
  314.                 wptr->pane = haswin_copywindow(org->pane);
  315.         if (org->slide)
  316.                 wptr->slide = haswin_copywindow(org->slide);
  317.         if (master)
  318.                 level = 0;
  319.         return(wptr);
  320. }
  321.  
  322. void haswin_deletewindow(window *wptr) {
  323.  
  324.         window  *wtmp;
  325.         _kernel_swi_regs regs;
  326.         buffer  buff;
  327.  
  328.         if ((int)wptr <= 0)
  329.                 return;
  330.         buff.i[0] = wptr->handle;
  331.         regs.r[1] = (int)&buff;
  332.         if (!haswin_swi(HASWIN_Delete_window, ®s))
  333.                 return;
  334.         if (wptr->picture) {
  335.                 if (!haswin_freeblock(wptr->picture))
  336.                         haswin_internalerror("haswin_deletewindow: haswin_free fails 1");
  337.                 wptr->picture = 0;
  338.         }
  339.         if (wptr == haswin_topwindow)
  340.                 haswin_topwindow = wptr->next;
  341.         else {
  342.                 /* scan the windows list looking for the one before wptr */
  343.                 wtmp = haswin_topwindow;
  344.                 while ((wtmp) && (wtmp->next != wptr))
  345.                         wtmp = wtmp->next;
  346.                 /* de-link wptr from the linked list */
  347.                 if (wtmp)
  348.                         wtmp->next = wptr->next;
  349.         }
  350.         if (!haswin_free(wptr))
  351.                 haswin_internalerror("haswin_deletewindow: haswin_free fails 2");
  352. }
  353.  
  354. /*
  355.  *      restrict the mouse to the window given.
  356.  *      Release the mouse if win == 0.
  357.  */
  358. int haswin_holdmousetowindow(window *win) {
  359.  
  360.         _kernel_swi_regs regs;
  361.         buffer           buff;
  362.         int              left, bott, rite, topp;
  363.  
  364.         if ((int)win <= 0) {
  365.                 left = bott = 0x8000;
  366.                 rite = topp = 0x7FFF;
  367.         } else {
  368.                 /* if the window is not open then return HASWIN_FALSE */
  369.                 haswin_updatewindowinfo(win);
  370.                 if ((haswin_getwindowflags(win) & WINDOW_OPEN) == 0)
  371.                         return(HASWIN_FALSE);
  372.                 /* get the bounding box size for the window */
  373.                 buff.i[0] = win->handle;
  374.                 regs.r[1] = (int)&buff;
  375.                 if (!haswin_swi(HASWIN_Get_window_outline, ®s))
  376.                         return(HASWIN_FALSE);
  377.                 left = buff.i[1];
  378.                 bott = buff.i[2];
  379.                 rite = buff.i[3];
  380.                 topp = buff.i[4];
  381.         }
  382.         /* use OS_Word to set the mouse rectangle */
  383.         buff.c[0] = 1;
  384.         buff.c[1] =  left       & 0xFF;
  385.         buff.c[2] = (left >> 8) & 0xFF;
  386.         buff.c[3] =  bott       & 0xFF;
  387.         buff.c[4] = (bott >> 8) & 0xFF;
  388.         buff.c[5] =  rite       & 0xFF;
  389.         buff.c[6] = (rite >> 8) & 0xFF;
  390.         buff.c[7] =  topp       & 0xFF;
  391.         buff.c[8] = (topp >> 8) & 0xFF;
  392.         regs.r[0] = 21;
  393.         regs.r[1] = (int)&buff;
  394.         return(haswin_swi(OS_Word, ®s));
  395. }
  396.  
  397. /*
  398.  *      convert window and x to a real screen x coord.
  399.  */
  400. int haswin_convertwinxtoscr(window *wptr, int x) {
  401.  
  402.         register int    *iptr;
  403.  
  404.         if ((int)wptr <= 0)
  405.                 return(x);
  406.         haswin_updatewindowinfo(wptr);
  407.         iptr = (int *)wptr->win;
  408.         x += iptr[0]-iptr[4];
  409.         if (x < iptr[0])
  410.                 x = iptr[0];
  411.         else if (x > iptr[2])
  412.                 x = iptr[2];
  413.         return(x+wptr->orgx);
  414. }
  415.  
  416. /*
  417.  *      convert window and y to a real screen y coord.
  418.  */
  419. int haswin_convertwinytoscr(window *wptr, int y) {
  420.  
  421.         register int    *iptr;
  422.  
  423.         if ((int)wptr <= 0)
  424.                 return(y);
  425.         haswin_updatewindowinfo(wptr);
  426.         iptr = (int *)wptr->win;
  427.         y += iptr[3]-iptr[5];
  428.         if (y < iptr[1])
  429.                 y = iptr[1];
  430.         else if (y > iptr[3])
  431.                 y = iptr[3];
  432.         return(y+wptr->orgy);
  433. }
  434.  
  435. /*
  436.  *      convert window and x,y to a real screen x,y pair.
  437.  */
  438. int haswin_convertwinxytoscr(window *wptr, int *x, int *y) {
  439.  
  440.         register int    *iptr;
  441.  
  442.         if ((int)wptr <= 0)
  443.                 return(HASWIN_FALSE);
  444.         haswin_updatewindowinfo(wptr);
  445.         iptr = (int *)wptr->win;
  446.         *x += iptr[0]-iptr[4];
  447.         if (*x < iptr[0])
  448.                 *x = iptr[0];
  449.         else if (*x > iptr[2])
  450.                 *x = iptr[2];
  451.         *x += wptr->orgx;
  452.         *y += iptr[3]-iptr[5];
  453.         if (*y < iptr[1])
  454.                 *y = iptr[1];
  455.         else if (*y > iptr[3])
  456.                 *y = iptr[3];
  457.         *y += wptr->orgy;
  458.         return(HASWIN_TRUE);
  459. }
  460.  
  461. /*
  462.  *      convert a real screen x coord and a window to the offset in the
  463.  *      window.
  464.  */
  465. int haswin_convertscrxtowin(window *wptr, int x) {
  466.  
  467.         register int    *iptr;
  468.  
  469.         if ((int)wptr <= 0)
  470.                 return(x);
  471.         haswin_updatewindowinfo(wptr);
  472.         iptr = (int *)wptr->win;
  473.         if (x < iptr[0])
  474.                 x = iptr[0];
  475.         else if (x > iptr[2])
  476.                 x = iptr[2];
  477.         x -= iptr[0]-iptr[4];
  478.         return(x-wptr->orgx);
  479. }
  480.  
  481. /*
  482.  *      convert a real screen y coord and a window to the offset in the
  483.  *      window.
  484.  */
  485. int haswin_convertscrytowin(window *wptr, int y) {
  486.  
  487.         register int    *iptr;
  488.  
  489.         if ((int)wptr <= 0)
  490.                 return(y);
  491.         haswin_updatewindowinfo(wptr);
  492.         iptr = (int *)wptr->win;
  493.         if (y < iptr[1])
  494.                 y = iptr[1];
  495.         else if (y > iptr[3])
  496.                 y = iptr[3];
  497.         y -= iptr[3]-iptr[5];
  498.         return(y-wptr->orgy);
  499. }
  500.  
  501. /*
  502.  *      convert a real screen x,y pair and a window to the offset in the
  503.  *      window.
  504.  */
  505. int haswin_convertscrxytowin(window *wptr, int *x, int *y) {
  506.  
  507.         register int    *iptr;
  508.  
  509.         if ((int)wptr <= 0)
  510.                 return(HASWIN_FALSE);
  511.         haswin_updatewindowinfo(wptr);
  512.         iptr = (int *)wptr->win;
  513.         if (*x < iptr[0])
  514.                 *x = iptr[0];
  515.         else if (*x > iptr[2])
  516.                 *x = iptr[2];
  517.         *x -= (iptr[0]-iptr[4])+wptr->orgx;
  518.         if (*y < iptr[1])
  519.                 *y = iptr[1];
  520.         else if (*y > iptr[3])
  521.                 *y = iptr[3];
  522.         *y -= (iptr[3]-iptr[5]) + wptr->orgy;
  523.         return(HASWIN_TRUE);
  524. }
  525.  
  526.